package com.ibeeking.found.content.c.rest.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ibeeking.found.content.c.rest.service.IBroadcastService;
import com.ibeeking.found.content.service.common.dos.BroadcastDO;
import com.ibeeking.found.content.service.common.dos.BroadcastGoodsDO;
import com.ibeeking.found.content.service.common.dos.BroadcastGoodsRelationDO;
import com.ibeeking.found.content.service.common.param.BroadcastParam;
import com.ibeeking.found.content.service.common.query.BroadcastPageQuery;
import com.ibeeking.found.content.service.common.query.BroadcastQuery;
import com.ibeeking.found.content.service.common.vo.BroadcastCount;
import com.ibeeking.found.content.service.common.vo.BroadcastCouponVO;
import com.ibeeking.found.content.service.common.vo.BroadcastGoodsVO;
import com.ibeeking.found.content.service.common.vo.BroadcastVO;
import com.ibeeking.found.content.service.mapper.BroadcastGoodsMapper;
import com.ibeeking.found.content.service.mapper.BroadcastGoodsRelationMapper;
import com.ibeeking.found.content.service.mapper.BroadcastMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @ClassName BroadcastServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2022-02-18 14:11
 **/
@Service
public class BroadcastServiceImpl extends ServiceImpl<BroadcastMapper, BroadcastDO> implements IBroadcastService {

    @Resource
    private BroadcastMapper broadcastMapper;
    @Resource
    private BroadcastGoodsRelationMapper broadcastGoodsRelationMapper;
    @Resource
    private BroadcastGoodsMapper broadcastGoodsMapper;

    @Override
    public List<BroadcastVO> list(BroadcastQuery broadcastQuery) {
        LambdaQueryWrapper<BroadcastDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(broadcastQuery.getRoomName()), BroadcastDO::getRoomName, broadcastQuery.getRoomName());
        queryWrapper.in(Collections3.isNotEmpty(broadcastQuery.getIds()), BroadcastDO::getId, broadcastQuery.getIds());
        queryWrapper.eq(broadcastQuery.getId() != null, BroadcastDO::getId, broadcastQuery.getId());
        queryWrapper.eq(broadcastQuery.getGroupId() != null, BroadcastDO::getGroupId, broadcastQuery.getGroupId());
        queryWrapper.in(Collections3.isNotEmpty(broadcastQuery.getGroupIds()), BroadcastDO::getGroupId, broadcastQuery.getGroupIds());
        queryWrapper.eq(broadcastQuery.getPublishStatus() != null, BroadcastDO::getPublishStatus, broadcastQuery.getPublishStatus());
        // 2-已结束 1-直播中 0-未开始
        if (ObjectUtil.isNotNull(broadcastQuery.getLiveStatus())) {
            Date now = new Date();
            if (broadcastQuery.getLiveStatus().equals(0)) {
                // 开始直播时间大于当前时间
                queryWrapper.ge(BroadcastDO::getStartTime, now);
            } else if (broadcastQuery.getLiveStatus().equals(1)) {
                // 开始直播时间小于当前时间 结束直播时间大于当前时间
                queryWrapper.le(BroadcastDO::getStartTime, now);
                queryWrapper.ge(BroadcastDO::getEndTime, now);
            } else if (broadcastQuery.getLiveStatus().equals(2)) {
                // 结束时间小于当前时间
                queryWrapper.le(BroadcastDO::getEndTime, now);
            }
        }
        queryWrapper.orderByDesc(BroadcastDO::getStartTime, BroadcastDO::getPublishTime, BroadcastDO::getCreateTime);
        List<BroadcastDO> broadcastDOs = broadcastMapper.selectList(queryWrapper);
        List<BroadcastVO> broadcastVOS = JsonUtils.jsonToList(broadcastDOs, BroadcastVO.class);
        // 开始时间之前为【未开始】，在开始后状态为【进行中】；在结束时间后为【已结束】
        for (BroadcastVO item : broadcastVOS) {
            Integer roomId = item.getRoomId();
            LambdaQueryWrapper<BroadcastGoodsRelationDO> relationQueryWrapper = new LambdaQueryWrapper<>();
            relationQueryWrapper.eq(BroadcastGoodsRelationDO::getRoomId, roomId);
            List<BroadcastGoodsRelationDO> broadcastGoodsRelationDoList = broadcastGoodsRelationMapper.selectList(relationQueryWrapper);
            List<Long> goodsIdList = broadcastGoodsRelationDoList.stream().map(BroadcastGoodsRelationDO::getGoodsId).distinct().collect(Collectors.toList());
            if (CollUtil.isNotEmpty(goodsIdList)) {
                List<BroadcastGoodsDO> broadcastGoodsDoList = broadcastGoodsMapper.selectBatchIds(goodsIdList);
                List<BroadcastGoodsVO> goodsVoList = JsonUtils.jsonToList(broadcastGoodsDoList, BroadcastGoodsVO.class);
                item.setGoodsVoList(goodsVoList);
            }
            item.setLiveStatus(getLiveStatus(item.getStartTime(), item.getEndTime()));

        }
        return broadcastVOS;
    }

    @Override
    public List<BroadcastGoodsVO> listOnsaledGoods(BroadcastQuery broadcastQuery) {
        return null;
    }

    @Override
    public List<BroadcastCouponVO> listOnsaledCoupon(BroadcastQuery broadcastQuery) {
        return null;
    }

    @Override
    public Page<BroadcastVO> pageList(BroadcastPageQuery broadcastPageQuery) {
        LambdaQueryWrapper<BroadcastDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(broadcastPageQuery.getPublishStatus() != null, BroadcastDO::getPublishStatus, broadcastPageQuery.getPublishStatus());
        queryWrapper.eq(broadcastPageQuery.getGroupId() != null, BroadcastDO::getGroupId, broadcastPageQuery.getGroupId());
        queryWrapper.like(StringUtils.isNotBlank(broadcastPageQuery.getRoomName()), BroadcastDO::getRoomName, broadcastPageQuery.getRoomName());
        queryWrapper.ge(StringUtils.isNotBlank(broadcastPageQuery.getCreateTimeStart()), BroadcastDO::getCreateTime, broadcastPageQuery.getCreateTimeStart());
        queryWrapper.le(StringUtils.isNotBlank(broadcastPageQuery.getCreateTimeEnd()), BroadcastDO::getCreateTime, broadcastPageQuery.getCreateTimeEnd());
        // 2-已结束 1-直播中 0-未开始
        if (ObjectUtil.isNotNull(broadcastPageQuery.getLiveStatus())) {
            Date now = new Date();
            if (broadcastPageQuery.getLiveStatus().equals(0)) {
                // 开始直播时间大于当前时间
                queryWrapper.ge(BroadcastDO::getStartTime, now);
            } else if (broadcastPageQuery.getLiveStatus().equals(1)) {
                // 开始直播时间小于当前时间 结束直播时间大于当前时间
                queryWrapper.le(BroadcastDO::getStartTime, now);
                queryWrapper.ge(BroadcastDO::getEndTime, now);
            } else if (broadcastPageQuery.getLiveStatus().equals(2)) {
                // 结束时间小于当前时间
                queryWrapper.le(BroadcastDO::getEndTime, now);
            }
        }
        queryWrapper.orderByDesc(BroadcastDO::getStartTime, BroadcastDO::getPublishTime, BroadcastDO::getCreateTime);
        Page<BroadcastDO> pages = broadcastMapper.selectPage(new Page<>(), queryWrapper);
        Page<BroadcastVO> broadcastVOPage = BeanUtil.convertPage(pages, BroadcastVO.class);
        List<BroadcastDO> doRecords = pages.getRecords();
        List<BroadcastVO> broadcastVOS = JsonUtils.jsonToList(doRecords, BroadcastVO.class);
        for (BroadcastVO item : broadcastVOS) {
            Integer roomId = item.getRoomId();
            LambdaQueryWrapper<BroadcastGoodsRelationDO> relationQueryWrapper = new LambdaQueryWrapper<>();
            relationQueryWrapper.eq(BroadcastGoodsRelationDO::getRoomId, roomId);
            List<BroadcastGoodsRelationDO> broadcastGoodsRelationDoList = broadcastGoodsRelationMapper.selectList(relationQueryWrapper);
            List<Long> goodsIdList = broadcastGoodsRelationDoList.stream().map(BroadcastGoodsRelationDO::getGoodsId).distinct().collect(Collectors.toList());
            if (CollUtil.isNotEmpty(goodsIdList)) {
                List<BroadcastGoodsDO> broadcastGoodsDoList = broadcastGoodsMapper.selectBatchIds(goodsIdList);
                List<BroadcastGoodsVO> goodsVoList = JsonUtils.jsonToList(broadcastGoodsDoList, BroadcastGoodsVO.class);
                item.setGoodsVoList(goodsVoList);
            }
            item.setLiveStatus(getLiveStatus(item.getStartTime(), item.getEndTime()));
        }
        broadcastVOPage.setRecords(broadcastVOS);
        return broadcastVOPage;
    }

    @Override
    public BroadcastVO view(Long id) {
        BroadcastDO broadcastDO = broadcastMapper.selectById(id);
        BroadcastVO broadcastVO = JsonUtils.fromJson(broadcastDO, BroadcastVO.class);
        broadcastVO.setLiveStatus(getLiveStatus(broadcastVO.getStartTime(), broadcastVO.getEndTime()));
        return broadcastVO;
    }

    @Override
    public List<BroadcastCount> countByGroup(List<Long> groupIds) {
        QueryWrapper<BroadcastDO> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .in(Collections3.isNotEmpty(groupIds), "group_id", groupIds)
                .select("count(1) as num, group_id as id")
                .groupBy(" group_id");
        List<Map<String, Object>> maps = broadcastMapper.selectMaps(queryWrapper);
        return JsonUtils.jsonToList(maps, BroadcastCount.class);
    }

    /**
     * 校验唯一性
     *
     * @param param
     */
    public void checkUnique(BroadcastParam param) {
        LambdaQueryWrapper<BroadcastDO> queryWrapper = new LambdaQueryWrapper<BroadcastDO>()
                .ne(param.getId() != null, BroadcastDO::getId, param.getId())
                .eq(StringUtils.isNotBlank(param.getRoomName()), BroadcastDO::getRoomName, param.getRoomName());
        List<BroadcastDO> dos = broadcastMapper.selectList(queryWrapper);
        if (Collections3.isNotEmpty(dos)) {
            throw new BusinessException("已经存在相同名字的直播间!");
        }
    }

    /**
     * 获取直播间开播状态
     *
     * @param startTime
     * @param endTime
     */
    public Integer getLiveStatus(String startTime, String endTime) {
        DateTime startDateTime = DateUtil.parseDateTime(startTime);
        DateTime endDateTime = DateUtil.parseDateTime(endTime);

        long startDateTimeMillis = startDateTime.getTime();
        long endDateTimeMillis = endDateTime.getTime();
        long now = System.currentTimeMillis();
        // 直播状态 2-已结束 1-直播中 0-未开始
        if (startDateTimeMillis > now) {
            // 当前时间 小于 开始时间 未开始
            return 0;
        } else if (startDateTimeMillis < now && now < endDateTimeMillis) {
            // 当前时间大于开始时间小于结束时间 进行中
            return 1;
        } else {
            // 已结束
            return 2;
        }
    }
}
